#ifndef __MYEPOLL_H
#define __MYEPOLL_H
#include "noncopyable.hpp"
#include <sys/epoll.h>
#include <vector>
#include <unordered_map>
#include <functional>
#include <memory>
#include <unistd.h> // for close()
#include <iostream>
#include <functional>
#include <cstring> // for strerror()
using std::function;
using std::vector;
using std::unordered_map;
class MyEpoll:Noncopyable
{
    using event_t = struct epoll_event;//结构体，告诉内核要监听什么事件
    using EventCallback = function<void(uint32_t)>;//文件描述符监听事件到来的处理函数
public:
    MyEpoll(int max_events = 1024):
        _efd(-1),
        _max_events(max_events) 
    {
        _efd = epoll_create1(0);//创建epoll实例
        if (_efd == -1) 
        {
            throw std::runtime_error("Failed to create epoll instance");
        }
        _events.resize(_max_events);//监听队列
    }
    ~MyEpoll()
    {
        if(_efd > 0)
            close(_efd);
    }
    int fd()
    {
        return _efd;
    }
    void add(int fd, uint32_t Epoll_events, EventCallback callback)
    {//添加事件监听，和处理函数绑定
        event_t event;//待监听事件结构
        event.events = Epoll_events;//待监听事件，位掩码
        event.data.fd = fd;//待监听套接字

        if(epoll_ctl(_efd, EPOLL_CTL_ADD, fd, &event) == -1)
        {//添加监听
            throw std::runtime_error("Failed to add file descriptor to epoll");
        }
        _callbacks[fd] = callback;//绑定事件处理函数
    };
    void del(int fd)
    {//删除对应的文件描述句柄
        if(epoll_ctl(_efd, EPOLL_CTL_DEL, fd, nullptr) == -1)
        {//删除待监听函数
            throw std::runtime_error("Failed to remove file descriptor to epoll");
        }
        _callbacks.erase(fd);//删除对应的事件处理函数
    };
    void mod(int fd, uint32_t Epoll_events)
    {//修改对应的监听
        event_t event;
        event.events = Epoll_events;
        event.data.fd = fd;
        if(epoll_ctl(_efd, EPOLL_CTL_MOD, fd, &event) == -1){
            throw std::runtime_error("Failed to mod file descriptor to epoll");
        }
    };

    void wait(int timeoutMs = -1)
    {
        int event_number = epoll_wait(_efd,_events.data(),_max_events,timeoutMs);//等待事件到来
         if (event_number == -1) 
         {
            if (errno == EINTR) 
            {
                return; // 被信号中断，直接返回
            }
            throw std::runtime_error("Error in epoll_wait");
        }
        for(int i = 0; i < event_number; i++)
        {
            int fd = _events[i].data.fd;
            uint32_t  Epoll_events =_events[i].events;
            if(_callbacks.count(fd) != 0)
            {
                _callbacks[fd](Epoll_events);
            }
        }
    }

private:
    int _efd;//epoll文件描述符
    int _max_events; // 最大事件数
    std::vector<event_t> _events; // 存放就绪事件的数组
    std::unordered_map<int, EventCallback> _callbacks; // 文件描述符到回调函数的映射                               
};

#endif //!MYEPOLL_H

